﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KylinORM.Utils
{
    /// <summary>
    /// 简单的IOC容器
    /// </summary>
    public static class IOCContainer
    {
        /// <summary>
        /// 当前已注册的接口
        /// </summary>
        private static Dictionary<Type, Type> typeHandlers = new Dictionary<Type, Type>();
        /// <summary>
        /// 当前已注册的实现类
        /// </summary>
        private static Dictionary<Type, object> objectHandlers = new Dictionary<Type, object>();

        /// <summary>
        /// 为指定接口注册实现类
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        public static void RegisterType<TFrom, TTo>() where TTo : TFrom
        {
            RegisterType(typeof(TFrom), typeof(TTo));
        }
        /// <summary>
        /// 为指定接口注册实现类
        /// </summary>
        /// <param name="tFrom"></param>
        /// <param name="tTo"></param>
        public static void RegisterType(Type tFrom,Type tTo)
        {
            lock (typeHandlers)
            {
                if (!tFrom.IsAssignableFrom(tTo))
                    throw new ArgumentOutOfRangeException("tTo", tTo.FullName + "不是" + tFrom.FullName + "的实现类。");

                if (!typeHandlers.ContainsKey(tFrom))
                    typeHandlers.Add(tFrom, tTo);

                typeHandlers[tFrom] = tTo;
            }
        }
        /// <summary>
        /// 创建指定接口的实现类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Resolve<T>()
        {
            return Resolve<T>(null);
        }
        /// <summary>
        /// 创建指定接口的实现类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="args"></param>
        /// <returns></returns>
        public static T Resolve<T>(params object[] args)
        {
            return (T)Activator.CreateInstance(typeHandlers[typeof(T)], args);
        }
        /// <summary>
        /// 返回指定接口的单例实现类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Singleton<T>()
        {
            return Singleton<T>(null);
        }
        /// <summary>
        /// 返回指定接口的单例实现类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="args"></param>
        /// <returns></returns>
        public static T Singleton<T>(params object[] args)
        {
            lock (objectHandlers)
            {
                if (objectHandlers.ContainsKey(typeof(T)))
                    return (T)objectHandlers[typeof(T)];

                objectHandlers.Add(typeof(T), Resolve<T>(args));
                return (T)objectHandlers[typeof(T)];
            }
        }

    }
}
